#include "sm4_utils.h"
#include <QWidget>
#include "file_transfer_client.h"
#include <QTcpSocket>
#include <QFile>
#include <QFileInfo>
#include <QProgressDialog>  // 核心头文件
#include "sm3_utils.h"
#include "sm4_utils.h"




FileTransferClient::FileTransferClient(const QString &host, quint16 port)
    : serverHost(host), serverPort(port) {}

bool FileTransferClient::uploadFile(const QString &username, const QString &filePath, QString &errorMsg, QWidget *parentForProgress) {
    QTcpSocket socket;
    socket.connectToHost(serverHost, serverPort);
    if (!socket.waitForConnected(3000)) {
        errorMsg = "连接服务器失败：" + socket.errorString();
        return false;
    }

    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        errorMsg = "无法打开文件：" + file.errorString();
        return false;
    }

    QFileInfo fileInfo(filePath);
    QString rawName = fileInfo.fileName();
    QString filename = resolveDuplicateFilename(username, rawName);  // 自动命名处理

    QByteArray plain = file.readAll();
    QByteArray key = sm3_hash(username).left(32).toUtf8().left(16);  // 取前16字节作为密钥
    QByteArray encrypted = sm4_encrypt(plain, key);
    file.close();

    qint64 totalSize = encrypted.size();
    QString cmd = QString("UPLOAD %1 %2 %3\n").arg(username, filename).arg(totalSize);
    socket.write(cmd.toUtf8());
    if (!socket.waitForBytesWritten(1000)) {
        errorMsg = "发送命令失败";
        return false;
    }

    // 进度条
    QProgressDialog progress("上传中...", "取消", 0, 100, parentForProgress);
    progress.setWindowModality(Qt::WindowModal);
    progress.setMinimumDuration(0);
    progress.setValue(0);

    qint64 sent = 0;
    while (sent < totalSize) {
        QByteArray chunk = encrypted.mid(sent, 4096);
        qint64 s = socket.write(chunk);
        if (s == -1 || !socket.waitForBytesWritten(1000)) {
            errorMsg = "上传过程中断";
            return false;
        }
        sent += s;
        progress.setValue((int)(sent * 100 / totalSize));
        if (progress.wasCanceled()) {
            errorMsg = "用户取消上传";
            return false;
        }
    }

    progress.setValue(100);
    socket.disconnectFromHost();
    return true;
}



bool FileTransferClient::downloadFile(const QString &username, const QString &filename, const QString &savePath, QString &errorMsg, QWidget *parentForProgress) {
    QTcpSocket socket;
    socket.connectToHost(serverHost, serverPort);
    if (!socket.waitForConnected(3000)) {
        errorMsg = "连接服务器失败：" + socket.errorString();
        return false;
    }

    QString cmd = QString("DOWNLOAD %1 %2\n").arg(filename, username);
    socket.write(cmd.toUtf8());
    if (!socket.waitForBytesWritten(1000) || !socket.waitForReadyRead(3000)) {
        errorMsg = "命令失败或服务器无响应";
        return false;
    }

    QByteArray header = socket.readLine();
    if (!header.startsWith("OK")) {
        errorMsg = QString::fromUtf8(header).trimmed();
        return false;
    }

    qint64 fileSize = header.split(' ')[1].trimmed().toLongLong();
    QProgressDialog progress("下载中...", "取消", 0, 100, parentForProgress);
    progress.setWindowModality(Qt::WindowModal);
    progress.setMinimumDuration(0);
    progress.setValue(0);

    QByteArray encrypted;
    qint64 received = 0;
    while (received < fileSize) {
        if (!socket.waitForReadyRead(3000)) {
            errorMsg = "下载过程中断";
            return false;
        }
        QByteArray chunk = socket.read(4096);
        encrypted.append(chunk);
        received += chunk.size();
        progress.setValue((int)(received * 100 / fileSize));
        if (progress.wasCanceled()) {
            errorMsg = "用户取消下载";
            return false;
        }
    }

    // 解密
    QByteArray key = sm3_hash(username).left(32).toUtf8().left(16);
    QByteArray plain = sm4_decrypt(encrypted, key);

    QFile outFile(savePath);
    if (!outFile.open(QIODevice::WriteOnly)) {
        errorMsg = "保存文件失败：" + outFile.errorString();
        return false;
    }

    outFile.write(plain);
    outFile.close();
    progress.setValue(100);
    socket.disconnectFromHost();
    return true;
}


QStringList FileTransferClient::listServerFiles(const QString &username, QString &errorMsg) {
    QStringList list;
    QTcpSocket socket;
    socket.connectToHost(serverHost, serverPort);
    if (!socket.waitForConnected(3000)) {
        errorMsg = "连接服务器失败：" + socket.errorString();
        return list;
    }

    QString cmd = QString("LIST_FILES %1\n").arg(username);
    socket.write(cmd.toUtf8());
    if (!socket.waitForBytesWritten(1000)) {
        errorMsg = "命令发送失败";
        return list;
    }

    if (!socket.waitForReadyRead(3000)) {
        errorMsg = "服务器无响应";
        return list;
    }

    QByteArray all;
    while (socket.bytesAvailable() || socket.waitForReadyRead(300)) {
        QByteArray chunk = socket.read(4096);
        if (chunk.isEmpty()) break;
        all += chunk;
    }

    QString result = QString::fromUtf8(all).trimmed();
    return result.split('\n', Qt::SkipEmptyParts);
}

bool FileTransferClient::deleteFile(const QString &filename, const QString &username, QString &errorMsg) {
    QTcpSocket socket;
    socket.connectToHost(serverHost, serverPort);
    if (!socket.waitForConnected(3000)) {
        errorMsg = "连接服务器失败：" + socket.errorString();
        return false;
    }

    QString cmd = QString("DELETE %1 %2\n").arg(filename, username);
    socket.write(cmd.toUtf8());
    if (!socket.waitForBytesWritten(1000)) {
        errorMsg = "命令发送失败";
        return false;
    }

    if (!socket.waitForReadyRead(2000)) {
        errorMsg = "服务器无响应";
        return false;
    }

    QByteArray response = socket.readLine().trimmed();
    if (response == "DELETE_SUCCESS") {
        return true;
    } else {
        errorMsg = "服务器返回：" + QString(response);
        return false;
    }
}

QString FileTransferClient::getLogContent(const QString &username, QString &errorMsg) {
    QTcpSocket socket;
    socket.connectToHost(serverHost, serverPort);
    if (!socket.waitForConnected(3000)) {
        errorMsg = "连接失败：" + socket.errorString();
        return "";
    }

    QString cmd = QString("GET_LOG %1\n").arg(username);
    socket.write(cmd.toUtf8());
    if (!socket.waitForBytesWritten(1000) || !socket.waitForReadyRead(3000)) {
        errorMsg = "服务器无响应";
        return "";
    }

    QByteArray allData;
    while (socket.bytesAvailable() || socket.waitForReadyRead(500)) {
        allData.append(socket.readAll());
    }

    if (allData.startsWith("ERROR")) {
        errorMsg = QString::fromUtf8(allData).trimmed();
        return "";
    }

    return QString::fromUtf8(allData);
}

QString FileTransferClient::resolveDuplicateFilename(const QString &username, const QString &filename) {
    QTcpSocket socket;
    socket.connectToHost(serverHost, serverPort);
    if (!socket.waitForConnected(3000)) return filename;

    QString cmd = QString("LIST_FILES %1\n").arg(username);
    socket.write(cmd.toUtf8());
    if (!socket.waitForBytesWritten(1000) || !socket.waitForReadyRead(3000)) return filename;

    QByteArray data;
    while (socket.bytesAvailable() || socket.waitForReadyRead(200)) {
        data.append(socket.readAll());
    }

    QStringList existing = QString::fromUtf8(data).split('\n', Qt::SkipEmptyParts);
    QString base = filename;
    QString suffix;
    int dotIndex = filename.lastIndexOf('.');
    if (dotIndex > 0) {
        base = filename.left(dotIndex);
        suffix = filename.mid(dotIndex);
    }

    QString newName = filename;
    int counter = 1;
    while (existing.contains(newName)) {
        newName = QString("%1(%2)%3").arg(base).arg(counter++).arg(suffix);
    }

    return newName;
}
